/**
 * Licensed under the Apache License Version 2.0.
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package net.interknit.knitter.cg.cfg;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import net.interknit.knitter.cg.util.Utils;

import org.jdom.Element;

/**
 *
 */
public class TypeEl
{
	private String className;
	private String restName;
	private boolean exclude = false;
	private boolean ignore = false;
	private String comments = "";
	private final Map<String, String> propertyComments = new Hashtable<String, String>();

	static final List<String> excludedTypes = new ArrayList<String>();
	static final List<String> ignoredTypes = new ArrayList<String>();

	static
	{
		excludedTypes.add("java.lang.Class");
		excludedTypes.add("java.sql.Connection");
		excludedTypes.add("java.lang.Exception");
		excludedTypes.add("java.lang.StackTraceElement");
		excludedTypes.add("java.util.BitSet");
	}

	static
	{
		ignoredTypes.add("javax.ws.rs.core.Response");
		ignoredTypes.add("javax.ws.rs.core.StreamingOutput");
		ignoredTypes.add("javax.ws.rs.core.Cookie");
		ignoredTypes.add("javax.ws.rs.core.NewCookie");
		ignoredTypes.add("javax.ws.rs.core.GenericEntity");
		ignoredTypes.add("javax.ws.rs.core.MultivaluedMap");
	}

	TypeEl()
	{
		;
	}

	public String getClassName()
	{
		return className;
	}

	public String getRestName()
	{
		return restName;
	}

	public boolean isExclude()
	{
		return exclude;
	}

	public boolean isIgnore()
	{
		return ignore;
	}

	public String getComments()
	{
		return comments != null && ! "".equals(comments) ? comments : "";
	}

	public String getPropertyComments(String propertyName)
	{
		String propComment = propertyComments.get(propertyName);

		if(propComment == null || propComment.isEmpty())
			propComment = "Property " + propertyName + " of type " + restName;

		return propComment;
	}

	public TypeEl(Element el)
	{
		if(el == null) throw new RuntimeException("type or target elements cannot be empty or null");

		String val = el.getAttributeValue("classname");
		className = Utils.cleanWhiteSpaces(val);

		val = el.getAttributeValue("restname");
		restName = val != null ? val : className;

		val = el.getAttributeValue("exclude");
		exclude = new Boolean(val).booleanValue();

		val = el.getAttributeValue("ignore");
		ignore = new Boolean(val).booleanValue();

		Element commentsEl = el.getChild("comments");

		if(commentsEl != null)
		{
			comments = commentsEl.getTextTrim();

			List<Element> propEls = commentsEl.getChildren("property");

			if(propEls != null && ! propEls.isEmpty())
			{
				for(Element propEl : propEls)
				{
					String propName = propEl.getAttributeValue("name");
					String propComment = propEl.getTextTrim();

					propComment = propComment != null ? propComment : "";

					if(propEl != null && ! propName.isEmpty())
					{
						propertyComments.put(propName, propComment);
					}
				}
			}
		}
	}

	@Override
	public String toString()
	{
		return "<type " +
				"classname=\"" + getClassName() + "\" " +
				"restname=\"" + getRestName() + "\" " +
				"exclude=\"" + isExclude() + "\" " +
				"ignore=\"" + isIgnore() + "\" " + ">" +
				"<comments>" + getComments() + "</comments>" +
				"</type>";
	}
}
